import _ from "lodash";
import type {MenuProps} from "antd";
import {Menu as MenuWrapper} from "antd";
import {FC, memo, useEffect, useState} from "react";
import {useLocation, useNavigate} from "react-router-dom";
import {memoCallBack} from "@/utils";

type MenuItem = Required<MenuProps>["items"][number];
interface Props {
    data: any[];
}

function getItem(
    label: React.ReactNode,
    key: React.Key,
    icon?: React.ReactNode,
    children?: MenuItem[],
    type?: "group"
): MenuItem {
    return {
        key,
        icon,
        children,
        label,
        type,
    } as MenuItem;
}

const handleGetMenuItem: any = (data: any[]): any =>
    _.map(data, ({path, title, children = [], icon = ""}) =>
        getItem(
            title,
            path,
            icon,
            _.map(children, item => getItem(item.title, item.path))
        )
    );

const Menu: FC<Props> = ({data}) => {
    const navigate = useNavigate();
    const location = useLocation();
    const items = handleGetMenuItem(data);

    const [openKeys, setOpenKeys] = useState<any[]>([data[0].path]);
    const [selectedKeys, setSelectedKeys] = useState<any[]>([]);

    const handleOpenChange: MenuProps["onOpenChange"] = (keys: any) => {
        const open = _.difference(keys, openKeys);
        setOpenKeys(open);
    };

    const handleMenuItem = ({key}: any) => {
        setSelectedKeys([key]);
        navigate(key);
    };

    useEffect(() => {
        let openKey = "";
        _.forEach(data, ({path}) => {
            if (location.pathname.includes(path)) {
                openKey = path;
            }
        });
        setOpenKeys([openKey]);
        setSelectedKeys([location.pathname]);
    }, [location, data]);

    return (
        <MenuWrapper
            selectedKeys={selectedKeys}
            style={{width: 200}}
            mode="inline"
            openKeys={openKeys}
            onOpenChange={handleOpenChange}
            items={items}
            onClick={handleMenuItem}
        />
    );
};
export default memo(Menu, memoCallBack);
